#include "bluetooth.h"

#include <QtBlueTooth/qBlueToothaddress.h>
#include <QtBlueTooth/qBlueToothlocaldevice.h>
#include <QtBlueTooth/qtBlueToothglobal.h>

const QString Bluetooth::serviceUuid = "00001101-0000-1000-8000-00805F9B34FB";

Bluetooth::Bluetooth(QObject* parent)
    : QObject(parent)
    , localDevice(new QBluetoothLocalDevice)
    , discoveryAgent(new QBluetoothDeviceDiscoveryAgent)
    , socket(nullptr)
{
    discoveryAgent->setInquiryType(QBluetoothDeviceDiscoveryAgent::GeneralUnlimitedInquiry);

    connect(discoveryAgent, &QBluetoothDeviceDiscoveryAgent::deviceDiscovered, this, &Bluetooth::deviceDiscovered, Qt::DirectConnection);
    connect(discoveryAgent, QOverload<QBluetoothDeviceDiscoveryAgent::Error>::of(&QBluetoothDeviceDiscoveryAgent::error), this, &Bluetooth::discoverError, Qt::DirectConnection);
}

Bluetooth::~Bluetooth()
{
    delete localDevice;
    delete discoveryAgent;
    delete socket;
}

void Bluetooth::restart()
{
    discoveryAgent->stop();
    discoveryAgent->start();
}

void Bluetooth::stop()
{
    discoveryAgent->stop();
}

void Bluetooth::connectDevice(const QBluetoothAddress& address, const QBluetoothUuid& uuid, QIODevice::OpenMode openMode)
{
    disconnectDevice();
    socket = new QBluetoothSocket(QBluetoothServiceInfo::RfcommProtocol);
    socket->connectToService(address, uuid, openMode);

    connect(socket, &QBluetoothSocket::connected, this, &Bluetooth::connected, Qt::DirectConnection);
    connect(socket, &QBluetoothSocket::readyRead, this, &Bluetooth::readyRead, Qt::DirectConnection);
    connect(socket, QOverload<QBluetoothSocket::SocketError>::of(&QBluetoothSocket::error), this, &Bluetooth::socketError, Qt::DirectConnection);
}

void Bluetooth::disconnectDevice()
{
    if (socket == nullptr)
    {
        return;    
    }

    disconnect(socket, nullptr, nullptr, nullptr);
    socket->abort();
    socket->deleteLater();
    socket = nullptr;
}

bool Bluetooth::isConnected() const
{
    return static_cast<bool>(socket != nullptr);
}

QByteArray Bluetooth::readAll()
{
    if (socket == nullptr)
    {
        return QByteArray();
    }
    return socket->readAll();
}

void Bluetooth::write(const QByteArray& dat)
{
    if (socket == nullptr)
    {
        return;
    }
    socket->write(dat); 
}
